package oceanwiki.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import oceanwiki.entity.Content;
import oceanwiki.entity.Doc;
import oceanwiki.exception.BusinessException;
import oceanwiki.exception.BusinessExceptionCode;
import oceanwiki.mapper.DocMapper;
import oceanwiki.req.DocQueryReq;
import oceanwiki.req.DocSaveReq;
import oceanwiki.resp.DocQueryResp;
import oceanwiki.resp.PageResp;
import oceanwiki.service.IContentService;
import oceanwiki.service.IDocService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import oceanwiki.util.CopyUtil;
import oceanwiki.util.RedisUtil;
import oceanwiki.util.RequestContent;
import oceanwiki.util.SnowFlake;
import oceanwiki.websocketserver.WebSocketServer;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XBJ
 * @since 2024-09-07
 */
@Service
public class DocServiceImpl extends ServiceImpl<DocMapper, Doc> implements IDocService {

    @Override
    public PageResp<DocQueryResp> listByName(DocQueryReq req) {
        QueryWrapper<Doc> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(req.getName()), "name", req.getName());

        //创建分页参数
        Page<Doc> page = new Page<>(req.getPage(), req.getSize());
        page = this.baseMapper.selectPage(page, queryWrapper);

        List<DocQueryResp> resps = CopyUtil.copyList(page.getRecords(), DocQueryResp.class);

        //创建返回对象
        PageResp<DocQueryResp> pageResp = new PageResp<>();
        pageResp.setList(resps);
        pageResp.setTotal(page.getTotal());
        return pageResp;
    }

    @Override
    public List<DocQueryResp> all(Long ebookId) {
        //使用sort列进行排序
        List<Doc> categories = this.baseMapper.selectList(new QueryWrapper<Doc>().eq("ebook_id", ebookId).orderByAsc("sort"));

        return CopyUtil.copyList(categories, DocQueryResp.class);
    }

    @Autowired
    private SnowFlake snowFlake;
    @Autowired
    private IContentService contentService;
    @Override
    public void save(DocSaveReq req) {
        Content content = CopyUtil.copy(req, Content.class);
        Doc doc = CopyUtil.copy(req, Doc.class);
        if (ObjectUtils.isEmpty(req.getId())) {
            //新增
            long id = snowFlake.nextId();
            doc.setId(id);
            doc.setViewCount(0);
            doc.setVoteCount(0);
            this.baseMapper.insert(doc);
            //更新内容
            content.setId(id);
            contentService.save(content);
        }else {
            //更新
            this.baseMapper.updateById(doc);
            boolean b = contentService.updateById(content);//更新内容
            if (!b) {//根据id更新失败，执行新增功能
                contentService.save(content);
            }
        }
    }

    @Override
    public void delete(List<Long> ids) {
        this.baseMapper.deleteBatchIds(ids);
    }

    @Resource
    RedisUtil redisUtil;
    @Resource
    RocketMQTemplate rocketMQTemplate;
    @Override
    public void vote(Long id) {
        //添加key
        String key = "DOC_VOTE_" + id + "_" + RequestContent.getRemoteAddr();
        if (redisUtil.validateRepeat(key, 3600*24)) {
            this.baseMapper.increaseVoteCount(id);
        } else {
            throw new BusinessException(BusinessExceptionCode.vote_repeat);
        }
        sendInfo(id);
    }

    @Async
    public void sendInfo(Long id) {
        //查询点赞文档信息
        Doc doc = this.baseMapper.selectById(id);
        String logId = MDC.get("LOG_ID");
        rocketMQTemplate.convertAndSend("VOTE_TOPIC", "你的文档 ["+doc.getName()+"] 被点赞");
    }

    @Override
    public void updateEbookInfo() {
        this.baseMapper.updateEbookInfo();
    }
}
